﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using l1cs.server.model.Instance;
using l1cs.server.model.skill;
using l1cs.server.serverpackets;
using System.Threading;

namespace l1cs.server.model
{
    public class L1HauntedHouse
    {
        private static Logger _log = Logger.getLogger( typeof( L1HauntedHouse ).FullName );

        public const int STATUS_NONE = 0;
        public const int STATUS_READY = 1;
        public const int STATUS_PLAYING = 2;

        private List<L1PcInstance> _members = new List<L1PcInstance>();
        private int _hauntedHouseStatus = STATUS_NONE;
        private int _winnersCount = 0;
        private int _goalCount = 0;

        private static L1HauntedHouse _instance;

        public static L1HauntedHouse getInstance()
        {
            if ( _instance == null )
            {
                _instance = new L1HauntedHouse();
            }
            return _instance;
        }

        private void readyHauntedHouse()
        {
            setHauntedHouseStatus( STATUS_READY );
            //TODO 優先度9 タイマースレッド
            //L1HauntedHouseReadyTimer hhrTimer = new L1HauntedHouseReadyTimer();
            //hhrTimer.begin();
            new Timer( new TimerCallback( L1HauntedHouseTimerSub ), null, 300000, Timeout.Infinite );
        }

        private void startHauntedHouse()
        {
            setHauntedHouseStatus( STATUS_PLAYING );
            int membersCount = getMembersCount();
            if ( membersCount <= 4 )
            {
                setWinnersCount( 1 );
            }
            else if ( 5 >= membersCount && membersCount <= 7 )
            {
                setWinnersCount( 2 );
            }
            else if ( 8 >= membersCount && membersCount <= 10 )
            {
                setWinnersCount( 3 );
            }
            foreach ( L1PcInstance pc in getMembersArray() )
            {
                L1SkillUse l1skilluse = new L1SkillUse();
                l1skilluse.handleCommands( pc,
                        L1SkillId.CANCELLATION, pc.getId(), pc.getX(), pc.getY(),
                        null, 0, L1SkillUse.TYPE_LOGIN );
                L1PolyMorph.doPoly( pc, 6284, 300, L1PolyMorph.MORPH_BY_NPC );
            }

            foreach ( L1Object l1object in L1World.getInstance().getObject() )
            {
                if ( l1object is L1DoorInstance )
                {
                    L1DoorInstance door = (L1DoorInstance)l1object;
                    if ( door.getMapId() == 5140 )
                    {
                        door.open();
                    }
                }
            }
        }

        public void endHauntedHouse()
        {
            setHauntedHouseStatus( STATUS_NONE );
            setWinnersCount( 0 );
            setGoalCount( 0 );
            foreach ( L1PcInstance pc in getMembersArray() )
            {
                if ( pc.getMapId() == 5140 )
                {
                    L1SkillUse l1skilluse = new L1SkillUse();
                    l1skilluse.handleCommands( pc,
                            L1SkillId.CANCELLATION, pc.getId(), pc.getX(),
                            pc.getY(), null, 0, L1SkillUse.TYPE_LOGIN );
                    L1Teleport.teleport( pc, 32624, 32813, (short)4, 5, true );
                }
            }
            clearMembers();
            foreach ( L1Object l1object in L1World.getInstance().getObject() )
            {
                if ( l1object is L1DoorInstance )
                {
                    L1DoorInstance door = (L1DoorInstance)l1object;
                    if ( door.getMapId() == 5140 )
                    {
                        door.close();
                    }
                }
            }
        }

        public void removeRetiredMembers()
        {
            L1PcInstance[] temp = getMembersArray();
            for ( int i = 0; i < temp.Length; i++ )
            {
                if ( temp[i].getMapId() != 5140 )
                {
                    removeMember( temp[i] );
                }
            }
        }

        public void sendMessage( int type, String msg )
        {
            foreach ( L1PcInstance pc in getMembersArray() )
            {
                pc.sendPackets( new S_ServerMessage( type, msg ) );
            }
        }

        public void addMember( L1PcInstance pc )
        {
            if ( !_members.Contains( pc ) )
            {
                _members.Add( pc );
            }
            if ( getMembersCount() == 1 && getHauntedHouseStatus() == STATUS_NONE )
            {
                readyHauntedHouse();
            }
        }

        public void removeMember( L1PcInstance pc )
        {
            _members.Remove( pc );
        }

        public void clearMembers()
        {
            _members.Clear();
        }

        public bool isMember( L1PcInstance pc )
        {
            return _members.Contains( pc );
        }

        public L1PcInstance[] getMembersArray()
        {
            return _members.ToArray();
        }

        public int getMembersCount()
        {
            return _members.Count;
        }

        private void setHauntedHouseStatus( int i )
        {
            _hauntedHouseStatus = i;
        }

        public int getHauntedHouseStatus()
        {
            return _hauntedHouseStatus;
        }

        private void setWinnersCount( int i )
        {
            _winnersCount = i;
        }

        public int getWinnersCount()
        {
            return _winnersCount;
        }

        public void setGoalCount( int i )
        {
            _goalCount = i;
        }

        public int getGoalCount()
        {
            return _goalCount;
        }

        //public class L1HauntedHouseReadyTimer extends TimerTask {

        //    public L1HauntedHouseReadyTimer() {
        //    }

        //    @Override
        public void L1HauntedHouseReadyTimerSub( object state )
        {
            startHauntedHouse();
            // TODO 優先度9 タイマースレッド
            //L1HauntedHouseTimer hhTimer = new L1HauntedHouseTimer();
            //hhTimer.begin();
            new Timer( new TimerCallback( L1HauntedHouseTimerSub ), null, 300000, Timeout.Infinite );
        }

        public void L1HauntedHouseReadyTimerBegin()
        {
            //Timer timer = new Timer();
            //timer.schedule( this, 90000 ); // 90秒くらい？
            new Timer( new TimerCallback( L1HauntedHouseReadyTimerSub ), null, 90000, Timeout.Infinite );
        }

        //}

        //public class L1HauntedHouseTimer extends TimerTask {

        //    public L1HauntedHouseTimer() {
        //    }

        //    @Override
        public void L1HauntedHouseTimerSub( object state )
        {
            endHauntedHouse();
        }

        //public void L1HauntedHouseTimerBegin()
        //{
        //    //Timer timer = new Timer();
        //    //timer.schedule( this, 300000 ); // 5分
        //    new Timer( new TimerCallback( L1HauntedHouseTimerSub ), null, 300000, Timeout.Infinite );
        //}
        //}
    }
}
